<template>
  <div class="search-box-container" ref="searchContainer">
    <!-- 搜索输入框 -->
    <div class="search-input-wrapper">
      <input
        v-model="searchKeyword"
        @input="handleInput"
        @focus="handleFocus"
        @blur="handleBlur"
        @keyup.enter="handleSearch"
        placeholder="请输入商品关键词"
        class="search-input"
        ref="searchInput"
      />
      <button @click="handleSearch" class="search-button">
        <svg class="search-icon" viewBox="0 0 1024 1024" width="16" height="16">
          <path d="M938.2 832.6L723.8 618.1c-2.5-2.5-5.3-4.4-7.9-6.4 36.2-55.6 57.3-121.8 57.3-193.1C773.3 222.8 614.6 64 418.7 64S64 222.8 64 418.6c0 195.9 158.8 354.6 354.6 354.6 71.3 0 137.5-21.2 193.1-57.3 2 2.7 3.9 5.4 6.4 7.9l214.4 214.4c14.8 14.8 38.9 14.8 53.7 0 14.8-14.9 14.8-39 0-53.7zM418.7 661.3c-134 0-242.7-108.6-242.7-242.7S284.7 176 418.7 176s242.7 108.6 242.7 242.7-108.7 242.6-242.7 242.6z" />
        </svg>
      </button>
    </div>

    <!-- 加载状态 -->
    <div v-if="loading" class="loading-indicator">
      加载中...
    </div>

    <!-- 搜索建议列表 -->
    <div v-if="showSuggestions && suggestions.length > 0" class="suggestions-dropdown">
      <div
        v-for="(item, index) in suggestions"
        :key="item.id"
        @click="selectSuggestion(item)"
        @mouseenter="hoveredIndex = index"
        @mouseleave="hoveredIndex = -1"
        :class="['suggestion-item', { 'hovered': hoveredIndex === index }]"
      >
        <span v-html="highlightPrefix(item.title, searchKeyword)"></span>
      </div>
    </div>

    <!-- 无匹配结果提示 -->
    <div v-if="showSuggestions && suggestions.length === 0 && searchKeyword && !loading" class="no-results">
      暂无相关商品
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { searchAPI } from '../services/api';

// 定义emit事件
const emit = defineEmits(['search']);

// 响应式数据
const searchKeyword = ref('');
const suggestions = ref([]);
const showSuggestions = ref(false);
const loading = ref(false);
const searchTimeout = ref(null);
const hoveredIndex = ref(-1);
const searchContainer = ref(null);
const searchInput = ref(null);

// 防抖处理输入事件
const handleInput = () => {
  // 清除之前的定时器
  if (searchTimeout.value) {
    clearTimeout(searchTimeout.value);
  }

  // 如果输入为空，清空搜索建议并隐藏列表
  if (!searchKeyword.value.trim()) {
    suggestions.value = [];
    showSuggestions.value = false;
    return;
  }

  // 设置新的定时器，延迟执行搜索建议
  searchTimeout.value = setTimeout(() => {
    fetchSuggestions();
  }, 300); // 300ms防抖
};

// 获取搜索建议
const fetchSuggestions = async () => {
  if (!searchKeyword.value.trim()) return;

  loading.value = true;
  try {
    // 调用后端接口获取搜索建议，限制最多10条结果
    const response = await searchAPI.prefixSearch(searchKeyword.value);
    suggestions.value = (response.data || []).slice(0, 10); // 最多显示10条
    showSuggestions.value = true;
  } catch (error) {
    console.error('获取搜索建议失败:', error);
    suggestions.value = [];
    // 接口请求失败时友好提示（这里可以使用ElMessage等组件）
    // 但不影响页面使用，继续显示空列表或隐藏列表
  } finally {
    loading.value = false;
  }
};

// 高亮前缀匹配部分
const highlightPrefix = (title, prefix) => {
  if (!prefix) return title;
  
  // 转义特殊字符，避免正则表达式错误
  const escapedPrefix = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  
  // 使用正则表达式匹配前缀（不区分大小写）
  const regex = new RegExp(`(^.*?)(${escapedPrefix})(.*?)`, 'i');
  const match = title.match(regex);
  
  if (match) {
    // 如果匹配成功，高亮前缀部分
    return `${match[1]}<span class="highlight">${match[2]}</span>${match[3]}`;
  }
  
  // 如果没有匹配到前缀，返回原始标题
  return title;
};

// 选择搜索建议
const selectSuggestion = (item) => {
  searchKeyword.value = item.title;
  showSuggestions.value = false;
  hoveredIndex.value = -1;
  
  // 触发搜索跳转（这里可以emit事件给父组件处理）
  triggerSearch(item.title);
};

// 处理搜索
const handleSearch = () => {
  if (searchKeyword.value.trim()) {
    showSuggestions.value = false;
    // 触发搜索跳转（这里可以emit事件给父组件处理）
    triggerSearch(searchKeyword.value);
  } else {
    // 如果搜索关键词为空，也触发搜索事件，让父组件处理
    triggerSearch('');
  }
};

// 触发搜索（可以emit事件给父组件）
const triggerSearch = (keyword) => {
  // 使用emit将搜索事件传递给父组件
  emit('search', keyword);
};

// 处理焦点事件
const handleFocus = () => {
  if (searchKeyword.value.trim() && suggestions.value.length > 0) {
    showSuggestions.value = true;
  }
};

// 处理失去焦点事件
const handleBlur = () => {
  // 延迟隐藏，确保点击建议项时不会立即隐藏
  setTimeout(() => {
    showSuggestions.value = false;
    hoveredIndex.value = -1;
  }, 200);
};

// 点击容器外部隐藏建议列表
const handleClickOutside = (event) => {
  if (searchContainer.value && !searchContainer.value.contains(event.target)) {
    showSuggestions.value = false;
    hoveredIndex.value = -1;
  }
};

// 获取当前搜索关键词的方法
const getCurrentKeyword = () => {
  return searchKeyword.value;
};

// 设置搜索关键词的方法
const setKeyword = (keyword) => {
  searchKeyword.value = keyword;
  
  // 如果设置为空字符串，隐藏建议列表
  if (!keyword.trim()) {
    showSuggestions.value = false;
    suggestions.value = [];
  }
};

// 挂载时添加事件监听
onMounted(() => {
  document.addEventListener('click', handleClickOutside);
});

// 卸载时移除事件监听
onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside);
  
  // 清除定时器
  if (searchTimeout.value) {
    clearTimeout(searchTimeout.value);
  }
});

// 暴露方法给父组件
defineExpose({
  getCurrentKeyword,
  setKeyword
});
</script>

<style scoped>
.search-box-container {
  position: relative;
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
}

.search-input-wrapper {
  display: flex;
  align-items: center;
  border: 1px solid #ddd;
  border-radius: 20px;
  overflow: hidden;
  background-color: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.search-input {
  flex: 1;
  padding: 12px 16px;
  font-size: 14px;
  border: none;
  outline: none;
  background: transparent;
}

.search-button {
  padding: 12px 20px;
  background-color: #2196f3;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.search-button:hover {
  background-color: #0b7dda;
}

.search-icon {
  fill: white;
}

.loading-indicator {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  padding: 10px;
  background-color: white;
  border: 1px solid #ddd;
  border-top: none;
  border-radius: 0 0 4px 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 100;
  text-align: center;
  color: #666;
}

.suggestions-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background-color: white;
  border: 1px solid #ddd;
  border-top: none;
  border-radius: 0 0 4px 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 100;
  max-height: 300px;
  overflow-y: auto;
}

.suggestion-item {
  padding: 12px 16px;
  cursor: pointer;
  border-bottom: 1px solid #eee;
  font-size: 14px;
}

.suggestion-item:last-child {
  border-bottom: none;
}

.suggestion-item.hovered,
.suggestion-item:hover {
  background-color: #f5f5f5;
}

.highlight {
  color: #e53935;
  font-weight: bold;
}

.no-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  padding: 12px 16px;
  background-color: white;
  border: 1px solid #ddd;
  border-top: none;
  border-radius: 0 0 4px 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 100;
  text-align: center;
  color: #666;
  font-size: 14px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .search-box-container {
    max-width: 100%;
  }
  
  .search-input {
    padding: 10px 12px;
    font-size: 16px; /* 移动端合适的字体大小 */
  }
  
  .search-button {
    padding: 10px 16px;
  }
  
  .suggestion-item {
    padding: 10px 12px;
    font-size: 16px;
  }
}
</style>